package com.hongxin.nw.netty.factory;

import com.hongxin.nw.netty.model.Transfer;
import com.hongxin.nw.netty.model.analysis.APCI;
import com.hongxin.nw.netty.model.analysis.ASDU;
import com.hongxin.nw.netty.model.analysis.ASDUmjcna1;
import com.hongxin.nw.netty.model.analysis.ASDUmrena1;
import com.hongxin.nw.netty.model.analysis.info.*;
import com.hongxin.nw.netty.utils.pools.CodeTypePools;
import com.hongxin.nw.netty.values.Catalogue;
import com.hongxin.nw.netty.values.StaticValue;
import com.hongxin.nw.netty.values.TypeIdentif;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @remark 报文解析工厂
 * @author: GuoXiaolin
 * @date 2019/5/24 17:51
 * @Version 1.0
 * @Descibe
 */
@Slf4j
public class AnalysisFactory {

    public static AnalysisFactory getInstance() {
        return new AnalysisFactory();
    }

    public Transfer analysisData(String code, ByteBuf byteBuf) throws Exception{
        int record = TypeIdentif.M_DEFAULT.getInt();
        int eType = CodeTypePools.getCodeType(code);

        //第一步:解析 A P C I
        APCI apci = new APCI();
        int idx = apci.analysisStr(byteBuf);
        int var = Integer.valueOf(apci.getContArea().substring(0,2),16);
        if (var == StaticValue.U_TEST_V){//测试帧
            return new Transfer(code, null, apci, TypeIdentif.M_HB.getInt(), eType,
                    Transfer.needRecord, Transfer.noNeedMq, null);
        }
        if (var == StaticValue.U_START_OK){//启动帧
            //U帧启动确认
            return new Transfer(code, null, apci, TypeIdentif.M_DEFAULT.getInt(), eType,
                    Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        if (var == StaticValue.U_STOP_OK){//停止帧
            //U帧停止确认.
            return new Transfer(code, null, apci, TypeIdentif.M_DEFAULT.getInt(), eType,
                    Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }

        //第二步: 解析ASDU
        ASDU asdu = new ASDU();
        idx = asdu.analysisStr(idx, byteBuf);

        //第三步: 解析业务数据
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_MD_NA_1.getInt()){//132
            if (asdu.getCot() == TypeIdentif.COT_SUMMON.getInt() || asdu.getCot() == TypeIdentif.COT_SPONTANEOUS.getInt()){
                //设备功率信息
                if (eType == TypeIdentif.EQUIPMENT_DIRECT.getInt()){//直流
                    List<DTmmdna1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        DTmmdna1 dataItem = new DTmmdna1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析直流功率数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
                }else{//交流
                    List<ExDTmmdna1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        ExDTmmdna1 dataItem = new ExDTmmdna1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析交流功率数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
                }
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_SP_NA_1.getInt()){//1
            if (asdu.getCot() == TypeIdentif.COT_SUMMON.getInt() || asdu.getCot() == TypeIdentif.COT_SPONTANEOUS.getInt()){
                //设备告警信息
                if (eType == TypeIdentif.EQUIPMENT_DIRECT.getInt()){//直流
                    List<DTmspna1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        DTmspna1 dataItem = new DTmspna1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析直流告警数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, record, eType, Transfer.noNeedRecord, Transfer.needMq, Catalogue.STATUS);
                }else{//交流
                    List<ExDTmspna1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        ExDTmspna1 dataItem = new ExDTmspna1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析交流告警数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, record, eType, Transfer.noNeedRecord, Transfer.needMq, Catalogue.STATUS);
                }
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_ME_NB_1.getInt()){//11
            if (asdu.getCot() == TypeIdentif.COT_SUMMON.getInt() || asdu.getCot() == TypeIdentif.COT_SPONTANEOUS.getInt()){
                //设备监测信息
                if (eType == TypeIdentif.EQUIPMENT_DIRECT.getInt()){//直流
                    List<DTmmenb1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        DTmmenb1 dataItem = new DTmmenb1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析直流设备监测数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, record, eType, Transfer.noNeedRecord, Transfer.needMq, Catalogue.STATUS);
//            
                }else{//交流
                    List<ExDTmmenb1> myl = new ArrayList<>();
                    for (int i = 0; i < asdu.getVsq(); i++){
                        ExDTmmenb1 dataItem = new ExDTmmenb1();
                        idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                        myl.add(dataItem);
                        log.info("解析交流设备监测数据:{}",dataItem.toString());
                    }
                    return new Transfer(code, asdu, myl, record, eType, Transfer.noNeedRecord, Transfer.needMq, Catalogue.STATUS);
                }
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_IT_NA_1.getInt()){ //15
            if (asdu.getCot() == TypeIdentif.COT_SUMMON_C.getInt()){
                //充电设备收到计数量总召命令后已上传累积量
                List<DTmitna1> myl = new ArrayList<>();
                for (int i = 0; i < asdu.getVsq(); i++){
                    DTmitna1 dataItem = new DTmitna1();
                    idx = dataItem.analysisStr(idx, byteBuf, asdu.getSq(), asdu.getInfoAdr(), asdu.getGun());
                    myl.add(dataItem);
//                    log.info("解析充电设备收到计数量总召命令后已上传累积量数据:{}",dataItem.toString());
                }
                return new Transfer(code, asdu, myl, TypeIdentif.M_DEFAULT.getInt(), eType,
                        Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_RE_NA_1.getInt()){//130
            ASDUmrena1 obj = new ASDUmrena1();
            idx = obj.analysisStr(idx, byteBuf);
            return analysisBusiData130(idx, byteBuf, code, asdu, eType, obj.getRecord());
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_M_JC_NA_1.getInt()){//134
            ASDUmjcna1 obj = new ASDUmjcna1();
            idx = obj.analysisStr(idx, byteBuf);
            return analysisBusiData134(idx, byteBuf, code, asdu, obj.getEtype());
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_C_CS_NA_1.getInt()){//103
            if (asdu.getCot()  == TypeIdentif.COT_ACTIVATION_CONFIRM.getInt()){
                //时钟同步已确认
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_C_SD_NA_1.getInt()){//133
            if (asdu.getCot() == TypeIdentif.COT_ACTIVATION_CONFIRM.getInt()){
                //远程升级已确认
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_C_CI_NA_1.getInt()){//101
            if (asdu.getCot() == TypeIdentif.COT_ACTIVATION_CONFIRM.getInt()){
                //计数量总召已确认
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
            if (asdu.getCot() == TypeIdentif.COT_ACTIVATION_TERMINATION.getInt()){
                //计数量总召已结束
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
        }
        if (asdu.getType() == TypeIdentif.IDENTIFY_C_IC_NA_1.getInt()){//100
            if (asdu.getCot() == TypeIdentif.COT_ACTIVATION_TERMINATION.getInt()){
                //总召已结束
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
            if (asdu.getCot() == TypeIdentif.COT_ACTIVATION_CONFIRM.getInt()){
                //总召已确认
                return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
            }
        }
        return new Transfer(code, asdu, apci, TypeIdentif.M_DEFAULT.getInt(), eType,
                Transfer.noNeedRecord, Transfer.noNeedMq, null);
    }

    //130 解析充电设备业务数据
    private Transfer analysisBusiData130(int idx, ByteBuf byteBuf, String code, ASDU asdu, int eType, int record) {
        if (TypeIdentif.M_RECORD_START_CHARGE.getInt() == record){
            //远程启动充电执行结果
            Mrena1_13 dataItem = new Mrena1_13();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析远程启动充电执行结果:{}",dataItem);
            return new Transfer(code, asdu, dataItem, record, eType, Transfer.needRecord, Transfer.needMq, Catalogue.STATUS);
        }
        if (TypeIdentif.M_RECORD_UPLOAD_DATA.getInt()==record){
            //充电记录上传数据
//            Mrena1_2 dataItem = new Mrena1_2();
            Mrena1_2_1 dataItem = new Mrena1_2_1();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析充电记录上传数据:{}",dataItem);
            return new Transfer(code, asdu, dataItem, record, eType, Transfer.needRecord, Transfer.needMq, Catalogue.PROCESS);
        }
        if (TypeIdentif.M_RECORD_CHARGE_PROCESS.getInt()==record){
            //充电过程中上传数据
//            Mrena1_17 dataItem = new Mrena1_17();
            Mrena1_17_1 dataItem = new Mrena1_17_1();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析充电过程中上传数据:{}",dataItem);
            return new Transfer(code, asdu, dataItem, record, eType, Transfer.needRecord, Transfer.needMq, Catalogue.STATUS);
        }
        if (TypeIdentif.M_RECORD_AUTH.getInt() == record){
            //鉴权数据
            Mrena1_1 dataItem = new Mrena1_1();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析鉴权数据结果:{}",dataItem);
            return new Transfer(code, asdu, dataItem, record, eType, Transfer.needRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_END_CHARGE.getInt()==record){
            //远程终止充电确认
            Mrena1_14 dataItem = new Mrena1_14();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析远程终止充电确认:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }

        if (TypeIdentif.M_RECORD_SET_PARAM.getInt()==record){
            //A.36充电设备数据上报参数设置结果
            Mrena1_18 dataItem = new Mrena1_18();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析充电设备数据上报参数设置结果:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_REQUEST_BILLING.getInt()==record){
            //A.7请求下发计费模型数据
            Mrena1_4 dataItem = new Mrena1_4();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析请求下发计费模型数据:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_BLACK_LIST.getInt() == record){
            //A.5 黑名单下发时上行数据
            Mrena1_11 dataItem = new Mrena1_11();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析黑名单下发时上行数据:{}",dataItem);
            return new Transfer(code, asdu, dataItem, record, eType, Transfer.needRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_KW_CONTROLLER.getInt() == record){
            //A.30 远程功率控制结果
            Mrena1_15 dataItem = new Mrena1_15();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析远程功率控制结果:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_BILLING.getInt()==record){
            //返回 A.9下发计费模型结果数据
            Mrena1_5 dataItem = new Mrena1_5();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析下发计费模型结果数据:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        if (TypeIdentif.M_RECORD_UPGRADE.getInt()==record){
            //A.32远程升级启动命令接收结果
            Mrena1_16 dataItem = new Mrena1_16();
            dataItem.analysisStr(idx, byteBuf);
            log.info("解析远程升级启动命令接收结果:{}",dataItem);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
    }

    //134 解析充电设备实时监测数据
    private  Transfer analysisBusiData134(int idx, ByteBuf byteBuf, String code, ASDU asdu, int eType) {
        //交流设备实时监测数据
        if (eType == TypeIdentif.EQUIPMENT_COMMUNICATION.getInt()){
            Mjcna1_1 dataItem = new Mjcna1_1();
            dataItem.analysisStr(idx, byteBuf);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        //直流设备实时监测数据
        if (eType == TypeIdentif.EQUIPMENT_DIRECT.getInt()){
            Mjcna1_2 dataItem = new Mjcna1_2();
            dataItem.analysisStr(idx, byteBuf);
            return new Transfer(code, asdu, dataItem, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
        }
        return new Transfer(code, asdu, null, TypeIdentif.M_DEFAULT.getInt(), eType,
                            Transfer.noNeedRecord, Transfer.noNeedMq, null);
    }
}
